<?php
declare(strict_types=1);

namespace app\controller\admin;

use app\BaseController;
use think\facade\{Db, Log, Cache};
use think\Request;

class PlatformConfigController extends BaseController
{
    /**
     * 获取配置列表
     */
    public function list(Request $request)
    {
        $where = [];
        
        // 配置组筛选
        if ($group = $request->param('group')) {
            $where[] = ['group_name', '=', $group];
        }
        
        $list = Db::name('platform_config')
            ->where($where)
            ->order('id', 'asc')
            ->select();
            
        return $this->success('获取成功', $list);
    }
    
    /**
     * 获取配置组
     */
    public function groups()
    {
        $groups = [
            [
                'name' => 'basic',
                'title' => '基础配置',
                'configs' => [
                    'site_name' => '平台名称',
                    'site_logo' => '平台Logo',
                    'site_desc' => '平台描述',
                    'icp_number' => 'ICP备案号'
                ]
            ],
            [
                'name' => 'storage',
                'title' => '存储配置',
                'configs' => [
                    'storage_type' => '存储方式',
                    'oss_access_key' => '阿里云AccessKey',
                    'oss_secret_key' => '阿里云SecretKey',
                    'oss_endpoint' => '阿里云Endpoint',
                    'oss_bucket' => '阿里云Bucket'
                ]
            ],
            [
                'name' => 'sms',
                'title' => '短信配置',
                'configs' => [
                    'sms_type' => '短信服务商',
                    'sms_access_key' => '短信AccessKey',
                    'sms_secret_key' => '短信SecretKey',
                    'sms_sign' => '短信签名'
                ]
            ],
            [
                'name' => 'payment',
                'title' => '支付配置',
                'configs' => [
                    'wechat_app_id' => '微信AppID',
                    'wechat_mch_id' => '微信商户号',
                    'wechat_key' => '微信支付密钥',
                    'alipay_app_id' => '支付宝AppID',
                    'alipay_private_key' => '支付宝私钥',
                    'alipay_public_key' => '支付宝公钥'
                ]
            ],
            [
                'name' => 'express',
                'title' => '快递配置',
                'configs' => [
                    'kuaidi100_key' => '快递100授权key',
                    'kuaidi100_customer' => '快递100Customer',
                    'kuaidi100_secret' => '快递100Secret'
                ]
            ]
        ];
        
        return $this->success('获取成功', $groups);
    }
    
    /**
     * 保存配置
     */
    public function save(Request $request)
    {
        $data = $this->validate($request->post(), [
            'group_name' => 'require',
            'configs' => 'require|array'
        ]);
        
        Db::startTrans();
        try {
            foreach ($data['configs'] as $key => $value) {
                // 更新或插入配置
                Db::name('platform_config')->where([
                    'group_name' => $data['group_name'],
                    'config_key' => $key
                ])->update([
                    'config_value' => is_array($value) ? json_encode($value) : $value,
                    'update_time' => date('Y-m-d H:i:s')
                ]);
            }
            
            // 清除缓存
            Cache::tag('platform_config')->clear();
            
            Db::commit();
            return $this->success('保存成功');
        } catch (\Exception $e) {
            Db::rollback();
            Log::error('保存配置失败: ' . $e->getMessage());
            return $this->error($e->getMessage());
        }
    }
    
    /**
     * 获取指定配置组
     */
    public function getGroup(Request $request, $group)
    {
        $configs = Db::name('platform_config')
            ->where('group_name', $group)
            ->column('config_value', 'config_key');
           
        // 处理JSON格式的配置值
        foreach ($configs as $key => $value) {
            if ($this->isJson($value)) {
                $configs[$key] = json_decode($value, true);
            }
        }
        
        return $this->success('获取成功', $configs);
    }
    
    /**
     * 判断是否为JSON字符串
     */
    protected function isJson($string)
    {
        json_decode($string);
        return json_last_error() === JSON_ERROR_NONE;
    }
    
    /**
     * 重置配置
     */
    public function reset(Request $request, $group)
    {
        try {
            // 获取默认配置
            $defaults = $this->getDefaultConfigs($group);
            if (empty($defaults)) {
                throw new \Exception('未找到默认配置');
            }
            
            Db::startTrans();
            try {
                foreach ($defaults as $key => $value) {
                    Db::name('platform_config')->where([
                        'group_name' => $group,
                        'config_key' => $key
                    ])->update([
                        'config_value' => is_array($value) ? json_encode($value) : $value,
                        'update_time' => date('Y-m-d H:i:s')
                    ]);
                }
                
                // 清除缓存
                Cache::tag('platform_config')->clear();
                
                Db::commit();
                return $this->success('重置成功');
            } catch (\Exception $e) {
                Db::rollback();
                throw $e;
            }
        } catch (\Exception $e) {
            Log::error('重置配置失败: ' . $e->getMessage());
            return $this->error($e->getMessage());
        }
    }
    
    /**
     * 获取默认配置
     */
    protected function getDefaultConfigs($group)
    {
        $defaults = [
            'basic' => [
                'site_name' => '裹裹大师',
                'site_logo' => '',
                'site_desc' => '快递寄件平台',
                'icp_number' => ''
            ],
            'storage' => [
                'storage_type' => 'local',
                'oss_access_key' => '',
                'oss_secret_key' => '',
                'oss_endpoint' => '',
                'oss_bucket' => ''
            ],
            'sms' => [
                'sms_type' => 'aliyun',
                'sms_access_key' => '',
                'sms_secret_key' => '',
                'sms_sign' => ''
            ],
            'payment' => [
                'wechat_app_id' => '',
                'wechat_mch_id' => '',
                'wechat_key' => '',
                'alipay_app_id' => '',
                'alipay_private_key' => '',
                'alipay_public_key' => ''
            ],
            'express' => [
                'kuaidi100_key' => '',
                'kuaidi100_customer' => '',
                'kuaidi100_secret' => ''
            ]
        ];
        
        return $defaults[$group] ?? [];
    }
    
    /**
     * 导出配置
     */
    public function export(Request $request)
    {
        try {
            $where = [];
            
            // 配置组筛选
            if ($group = $request->param('group')) {
                $where[] = ['group_name', '=', $group];
            }
            
            $configs = Db::name('platform_config')
                ->where($where)
                ->select()
                ->toArray();
                
            // 准备导出数据
            $data = [];
            foreach ($configs as $config) {
                $value = $config['config_value'];
                if ($this->isJson($value)) {
                    $value = json_decode($value, true);
                }
                
                $data[] = [
                    'group_name' => $config['group_name'],
                    'config_key' => $config['config_key'],
                    'config_value' => $value,
                    'description' => $config['description']
                ];
            }
            
            // 导出文件名
            $filename = 'platform_config_' . ($group ?: 'all') . '_' . date('YmdHis') . '.json';
            
            return response()->data(json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT))
                ->header([
                    'Content-Type' => 'application/json',
                    'Content-Disposition' => 'attachment; filename="' . $filename . '"'
                ]);
        } catch (\Exception $e) {
            Log::error('导出配置失败: ' . $e->getMessage());
            return $this->error($e->getMessage());
        }
    }
    
    /**
     * 导入配置
     */
    public function import(Request $request)
    {
        try {
            $file = $request->file('file');
            if (!$file) {
                throw new \Exception('请选择配置文件');
            }
            
            // 读取文件内容
            $content = file_get_contents($file->getPathname());
            $data = json_decode($content, true);
            if (!$data) {
                throw new \Exception('配置文件格式错误');
            }
            
            Db::startTrans();
            try {
                foreach ($data as $item) {
                    if (!isset($item['group_name']) || !isset($item['config_key']) || !isset($item['config_value'])) {
                        throw new \Exception('配置数据格式错误');
                    }
                    
                    // 更新或插入配置
                    Db::name('platform_config')->where([
                        'group_name' => $item['group_name'],
                        'config_key' => $item['config_key']
                    ])->update([
                        'config_value' => is_array($item['config_value']) ? json_encode($item['config_value']) : $item['config_value'],
                        'description' => $item['description'] ?? '',
                        'update_time' => date('Y-m-d H:i:s')
                    ]);
                }
                
                // 清除缓存
                Cache::tag('platform_config')->clear();
                
                Db::commit();
                return $this->success('导入成功');
            } catch (\Exception $e) {
                Db::rollback();
                throw $e;
            }
        } catch (\Exception $e) {
            Log::error('导入配置失败: ' . $e->getMessage());
            return $this->error($e->getMessage());
        }
    }
    
    /**
     * 备份配置
     */
    public function backup()
    {
        try {
            $configs = Db::name('platform_config')->select()->toArray();
            
            // 生成备份文件名
            $filename = 'config_backup_' . date('YmdHis') . '.json';
            $filepath = runtime_path() . 'backup/' . $filename;
            
            // 确保目录存在
            if (!is_dir(dirname($filepath))) {
                mkdir(dirname($filepath), 0755, true);
            }
            
            // 写入备份文件
            file_put_contents($filepath, json_encode($configs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
            
            // 记录备份日志
            Db::name('platform_operation_log')->insert([
                'admin_id' => request()->adminId,
                'operation_type' => '备份',
                'operation_content' => '备份平台配置，文件名：' . $filename,
                'create_time' => date('Y-m-d H:i:s')
            ]);
            
            return $this->success('备份成功');
        } catch (\Exception $e) {
            Log::error('备份配置失败: ' . $e->getMessage());
            return $this->error($e->getMessage());
        }
    }
    
    /**
     * 获取备份列表
     */
    public function backupList()
    {
        try {
            $path = runtime_path() . 'backup/';
            if (!is_dir($path)) {
                return $this->success('获取成功', []);
            }
            
            $files = glob($path . 'config_backup_*.json');
            $list = [];
            
            foreach ($files as $file) {
                $filename = basename($file);
                $list[] = [
                    'filename' => $filename,
                    'size' => filesize($file),
                    'create_time' => date('Y-m-d H:i:s', filectime($file))
                ];
            }
            
            // 按创建时间倒序排序
            usort($list, function($a, $b) {
                return strtotime($b['create_time']) - strtotime($a['create_time']);
            });
            
            return $this->success('获取成功', $list);
        } catch (\Exception $e) {
            Log::error('获取备份列表失败: ' . $e->getMessage());
            return $this->error($e->getMessage());
        }
    }
    
    /**
     * 恢复配置
     */
    public function restore(Request $request)
    {
        $filename = $request->param('filename');
        if (!$filename) {
            return $this->error('请选择备份文件');
        }
        
        try {
            $filepath = runtime_path() . 'backup/' . $filename;
            if (!file_exists($filepath)) {
                throw new \Exception('备份文件不存在');
            }
            
            // 读取备份文件
            $content = file_get_contents($filepath);
            $configs = json_decode($content, true);
            if (!$configs) {
                throw new \Exception('备份文件格式错误');
            }
            
            Db::startTrans();
            try {
                foreach ($configs as $config) {
                    Db::name('platform_config')->where([
                        'group_name' => $config['group_name'],
                        'config_key' => $config['config_key']
                    ])->update([
                        'config_value' => $config['config_value'],
                        'description' => $config['description'],
                        'update_time' => date('Y-m-d H:i:s')
                    ]);
                }
                
                // 清除缓存
                Cache::tag('platform_config')->clear();
                
                // 记录操作日志
                Db::name('platform_operation_log')->insert([
                    'admin_id' => request()->adminId,
                    'operation_type' => '恢复',
                    'operation_content' => '从备份文件恢复平台配置，文件名：' . $filename,
                    'create_time' => date('Y-m-d H:i:s')
                ]);
                
                Db::commit();
                return $this->success('恢复成功');
            } catch (\Exception $e) {
                Db::rollback();
                throw $e;
            }
        } catch (\Exception $e) {
            Log::error('恢复配置失败: ' . $e->getMessage());
            return $this->error($e->getMessage());
        }
    }
} 